package com.lin.manager.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lin.manager.common.utils.StrUtils;
import com.lin.manager.system.dao.SysMenuDao;
import com.lin.manager.system.dao.SysRoleMenuDao;
import com.lin.manager.system.entity.SysMenuEntity;
import com.lin.manager.system.entity.SysRoleMenuEntity;
import com.lin.manager.login.model.vo.LoginUserVo;
import com.lin.manager.system.model.vo.RouteVo;
import com.lin.manager.system.service.SysRoleMenuService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @作者: 林江
 * @创建时间: 2024/3/12
 * @功能:
 */
@Service
public class SysRoleMenuServiceImpl implements SysRoleMenuService {
    @Autowired
    SysRoleMenuDao sysRoleMenuDao;
    @Autowired
    SysMenuDao sysMenuDao;

    @Override
    public List<SysRoleMenuEntity> findByRoleId(Integer roleId) {
        LambdaQueryWrapper<SysRoleMenuEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRoleMenuEntity::getRoleId, roleId);
        return sysRoleMenuDao.selectList(wrapper);
    }

    @Override
    public void binding(List<SysRoleMenuEntity> roleMenus) {
        for (SysRoleMenuEntity roleMenu : roleMenus) {
            sysRoleMenuDao.insert(roleMenu);
        }
    }

    @Override
    public void deleteByRoleId(Integer roleId) {
        sysRoleMenuDao.delete(new LambdaQueryWrapper<SysRoleMenuEntity>().eq(SysRoleMenuEntity::getRoleId, roleId));
    }

    @Override
    public void deleteByMenuId(String menuId) {
        sysRoleMenuDao.delete(new LambdaQueryWrapper<SysRoleMenuEntity>().eq(SysRoleMenuEntity::getMenuId, menuId));
    }

    @Override
    public LoginUserVo findLoginMenuByRoleIds(List<Integer> roleIds) {
        List<SysRoleMenuEntity> roleMenus = sysRoleMenuDao.selectList(new LambdaQueryWrapper<SysRoleMenuEntity>().in(SysRoleMenuEntity::getRoleId, roleIds));

        LoginUserVo userVo = new LoginUserVo();
        if (roleMenus.size() > 0) {
            LambdaQueryWrapper<SysMenuEntity> wrapper = new QueryWrapper<SysMenuEntity>().lambda()
                    .in(SysMenuEntity::getId,
                            roleMenus.stream().map(SysRoleMenuEntity::getMenuId).collect(Collectors.toSet())
                    ).orderByAsc(SysMenuEntity::getSorted);
            List<SysMenuEntity> list = sysMenuDao.selectList(wrapper);

            List<RouteVo> routes = getRoutes(list);
            userVo.setRoutes(routes);
            userVo.setMenus(list.stream().filter(i -> i.getType() != 3).map(SysMenuEntity::getPath).filter(StringUtils::isNotBlank).collect(Collectors.toList()));
        }
        return userVo;
    }


    public List<RouteVo> getRoutes(List<SysMenuEntity> menus) {
        List<RouteVo> routeVos = new ArrayList<>();

        menus.stream().filter(menu -> menu.getPid().equals(NumberUtils.INTEGER_ZERO))
                .forEach(item -> {
                    RouteVo routeVo = createRoute(item);
                    // 递归
                    routeVo.setChildren(getChildRoutes(menus.stream().filter(menu -> !menu.getPid().equals(NumberUtils.INTEGER_ZERO)).collect(Collectors.toList()), item.getId()));
                    routeVos.add(routeVo);
                });

        return routeVos;
    }


    private List<RouteVo> getChildRoutes(List<SysMenuEntity> childs, Integer pid) {
        List<RouteVo> routes = new ArrayList<>();
        for (SysMenuEntity child : childs) {
            if (child.getType() == 3) {
                continue;
            }
            if (child.getPid().equals(pid)) {
                RouteVo routeChildVo = createRoute(child);
                routeChildVo.setChildren(getChildRoutes(childs, child.getId()));
                routes.add(routeChildVo);
            }
        }
        return routes;
    }

    private RouteVo createRoute(SysMenuEntity item) {
        RouteVo routeVo = new RouteVo();
        routeVo.setPath(item.getPath());
        routeVo.setComponent(item.getComponent());
        routeVo.setHidden(item.getHidden() == 0 ? false : true);
        routeVo.setName(StrUtils.capitalize(item.getPath()));
        routeVo.setMeta(
                RouteVo.Meta.builder()
                        .title(item.getName())
                        .icon(item.getIcon())
                        .isCache(item.getIsCache() == 0 ? false : true)
                        .build()
        );
        if (item.getType() == 1) {
            routeVo.setComponent("Layout");
        }
        return routeVo;
    }
}
